package hotel.base.oversea.utils;

import hotel.base.oversea.constant.enums.SwitchBedIdEnums;
import hotel.base.oversea.constant.CommonConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.util.Arrays;
import java.util.HashSet;

/**
 * 校验相关工具类
 */

@Slf4j
public class CompareUtil {

    /**
     * 比较两个字符串相似度
     * @param areaName 地区
     * @param str 酒店名称1
     * @param target 酒店名称2
     * @return boolean
     */
    public static boolean getStrPre(String areaName,String str,String target){
        boolean ret = false;
        str = hotelNameReplace(areaName,str);
        target = hotelNameReplace(areaName,target);

        float pre = getSimilarityRatio(str, target);

        float pre2 = getSimilarityRatio(target, str);




        if(pre>=CommonConstants.COMPARE_PER || pre2>=CommonConstants.COMPARE_PER || str.indexOf(target) != -1 || target.indexOf(str) != -1){
            ret = true;
        }

        return ret;
    }

    /**
     * 小数点向左移动6位
     * @param d
     * @return
     */
    public static double rad(double d) {
        return d * Math.PI / 180.00; // 角度转换成弧度
    }

    /**
     * 根据经纬度计算两点之间的距离（单位米）
     * @param longitude1
     * @param latitude1
     * @param longitude2
     * @param latitude2
     * @return
     */
    public static double algorithm(double longitude1, double latitude1, double longitude2, double latitude2) {

        double Lat1 = rad(latitude1); // 纬度
        double Lat2 = rad(latitude2);

        double a = Lat1 - Lat2;// 两点纬度之差
        double b = rad(longitude1) - rad(longitude2); // 经度之差

        double s = 2 * Math.asin(Math
                .sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(Lat1) * Math.cos(Lat2) * Math.pow(Math.sin(b / 2), 2)));// 计算两点距离的公式

        s = s * 6378137.0;// 弧长乘地球半径（半径为米）
        s = Math.round(s * 10000d) / 10000d;// 精确距离的数值
        // 四舍五入 保留一位小数
        //DecimalFormat df = new DecimalFormat("#.0");
        return s;

    }


    /**
     * 小数点向左移动6位
     *
     * @param d
     * @return
     */
    public static double getDouble(double d) {
        return Double.valueOf(String.format("%.6f", d / 1000000));
    }


    /**
     * 比較中文两个字符串的相似度
     * @param str
     * @param target
     * @return
     */
    public static float getSimilarityRatio(String str, String target) {

        int d[][]; // 矩阵
        int n = str.length();
        int m = target.length();
        int i; // 遍历str的
        int j; // 遍历target的
        char ch1; // str的
        char ch2; // target的
        int temp; // 记录相同字符,在某个矩阵位置值的增量,不是0就是1
        if (n == 0 || m == 0) {
            return 0;
        }
        d = new int[n + 1][m + 1];
        for (i = 0; i <= n; i++) { // 初始化第一列
            d[i][0] = i;
        }

        for (j = 0; j <= m; j++) { // 初始化第一行
            d[0][j] = j;
        }

        for (i = 1; i <= n; i++) { // 遍历str
            ch1 = str.charAt(i - 1);
            // 去匹配target
            for (j = 1; j <= m; j++) {
                ch2 = target.charAt(j - 1);
                if (ch1 == ch2 || ch1 == ch2 + 32 || ch1 + 32 == ch2) {
                    temp = 0;
                } else {
                    temp = 1;
                }
                // 左边+1,上边+1, 左上角+temp取最小
                d[i][j] = Math.min(Math.min(d[i - 1][j] + 1, d[i][j - 1] + 1), d[i - 1][j - 1] + temp);
            }
        }

        return (1 - (float) d[n][m] / Math.max(str.length(), target.length())) * 100F;
    }

    /**
     * 过滤酒店相关鍵字
     * @param areaName 地区
     * @param hotelName 所需要被过滤的字符串
     * @return
     */
    public static String hotelNameReplace(String areaName,String hotelName){
        //過濾地區
        if(!StringUtils.isEmpty(areaName)){
            hotelName = hotelName.replaceAll(areaName,"");
        }

        //過濾英文括弧
        hotelName = hotelName.replaceAll("\\(","").replaceAll("\\)","");
        //過濾中文括弧
        hotelName = hotelName.replaceAll("（","").replaceAll("）","");

        String[] hotelNames = CommonConstants.HOTEL_NAME;
        for (String repName : hotelNames) {
            hotelName = hotelName.replaceAll(repName,"");
        }
        return hotelName;
    }

    /**
     * 酒店房型名称相似度对比
     */
    public static boolean isSimilAr(String mtRoomName,String swRoomName){
        boolean flag=false;
        mtRoomName=hotelRoomNameReplace(mtRoomName);
        swRoomName=hotelRoomNameReplace(swRoomName);
        //首先先进行关键字查询
        /*flag=existsKeyword(mtRoomName,swRoomName);
        if(flag){
            return flag;
        }*/
        //如果关键字查询不可以，在进行字查询
        float similarRate=getSimilarityRatio(mtRoomName,swRoomName);
        if(similarRate>=CommonConstants.COMPARE_ROOM_NAMR_PRE){
            flag = true;
        }
        return flag;
    }
    /**
     * 判断是否含有某个字符
     */
    public static boolean existsKeyword(String mtRoomName,String swRoomName){
        String[] names=CommonConstants.HOTEL_KEYWORD_ROOM_NAME;
        tab:for(String s:names){
            if(mtRoomName.contains(s)&&swRoomName.contains(s)){
                return true;
            }else{
                continue tab;
            }
        }
        return false;
    }

    /**
     * 酒店房型有无窗对比
     *  携程 0 表示无窗 1 表示部分有窗 2 有窗
     *  美团 0 有窗 1表示部分有窗 2 无窗
     *  发现如果俩个值加起来等于2 就是同一房型
     */
    public static boolean isSimilarByWindow(int mtRoomWindow,int swRoomWindow){
        int result=mtRoomWindow+swRoomWindow;
        if(result==2){
            return true;
        }
        return false;
    }

    /**
     * 酒店房型楼层对比
     * 携程 7-23  22
     * 美团 7-23  23
     * 规则:携程的floor必须在美团的区间内
     */
    public static boolean isSimilarByFloor(String mtFloor,String swFloor){
       boolean isSimilar=false;
       //首先直接都是区间的情况 携程是7-23 美团 2-3  携程 1 美团 2
        if(mtFloor.equals(swFloor)){
            isSimilar=true;
        }
        String[] mtFloors=splibit("-",mtFloor);
        String[] swFloors=splibit("-",swFloor);
        //1.俩个都是区间
        if(mtFloors.length>1&&swFloors.length>1){
            int mtStart=Integer.valueOf(mtFloors[0]);
            int mtEnd=Integer.valueOf(mtFloors[1]);
            int swStart=Integer.valueOf(swFloors[0]);
            int swEnd=Integer.valueOf(swFloors[1]);
            if(mtStart<=swStart&&swEnd<=mtEnd){
                isSimilar=true;
            }
        }
        //2.美团是区间 携程是数值
        if(mtFloors.length>1&&swFloors.length==1){
            int mtStart=Integer.valueOf(mtFloors[0]);
            int mtEnd=Integer.valueOf(mtFloors[1]);
            int swStart=Integer.valueOf(swFloors[0]);
            if(mtStart<=swStart&&swStart<=mtEnd){
                isSimilar=true;
            }
        }
        //3.美团是具体数值 携程是区间 这个暂不考虑
        return  isSimilar;
    }

    /**
     * 根据字符串拆分数据
     */
    public static String[] splibit(String pattern,String target){
        return target.split(pattern);
    }


    /**
     * 过滤房型关键字
     * @param roomName 房型名称
     */
    public static String hotelRoomNameReplace(String roomName){
        //過濾英文括弧
        roomName = roomName.replaceAll("\\(","").replaceAll("\\)","");
        //過濾中文括弧
        roomName = roomName.replaceAll("（","").replaceAll("）","");
        String[] hotelRoomNames=CommonConstants.HOTEL_ROOM_NAME;
        for(String repName:hotelRoomNames){
            roomName=replaceAll(roomName,repName,"");
        }
        return roomName;
    }
    public static String replaceAll(String parent,String targetEle,String replaceEle ) {
        if( parent.indexOf(targetEle) == -1 ) {
            return parent;
        }else {
            int beginIndex = parent.indexOf(targetEle);
            int endIndex = beginIndex + targetEle.length();
            return parent.substring(0,beginIndex) + replaceEle + replaceAll(parent.substring(endIndex), targetEle, replaceEle);
        }

    }

    /**
     * 过滤床型关键字
     * @param roomBedName
     */
    public static String hotelRoomBedNameReplace(String roomBedName){
        //過濾英文括弧
        roomBedName = roomBedName.replaceAll("\\(","").replaceAll("\\)","");
        //過濾中文括弧
        roomBedName = roomBedName.replaceAll("（","").replaceAll("）","");
        String[] hotelRoomNames=CommonConstants.BED_NAME;
        for(String repName:hotelRoomNames){
            roomBedName.replaceAll(repName,"");
        }
        return roomBedName;
    }

    /**
     * 床型相似度匹配
     * @param mtRoomBedName
     * @param swBedRoomName
     * @return
     */
    public static boolean isSimilByBedName(String mtRoomBedName,String swBedRoomName){
        boolean flag=false;
        mtRoomBedName=hotelRoomBedNameReplace(mtRoomBedName);
        swBedRoomName=hotelRoomBedNameReplace(swBedRoomName);
        float similarRate=getSimilarityRatio(mtRoomBedName,swBedRoomName);
        //判断相似度
        if(similarRate>=CommonConstants.COMPARE_ROOM_BED_NAMR_PRE){
            flag = true;
        }
        return flag;
    }

    /**
     * 根据床型名称获取对应的房型id
     * @param
     */
    public static int getBedId(String bedName,int ParentId){
        String[] bedNames=new String[]{"双人床","圆床","水床","榻榻米","炕","单人床","上下铺","太空舱","胶囊床","沙发床","小型双人床","大床","特大床"};
        int[] bedIds=new int[]{365,366,367,368,369,370,657,851,852,1144,4059,4060,4061};
        //记录相似度最高的比例
        float moreSimilar=0.0f;
        //记录相似度最高的id
        int bedId=0;
        tab:for(int i=0;i<bedNames.length;i++){
            //过滤关键字,提高精确度
            bedName=hotelRoomBedNameReplace(bedName);
            bedNames[i]=hotelRoomBedNameReplace(bedNames[i]);
            //相似度根据算法计算出来
            float similarRate=getSimilarityRatio(bedName,bedNames[i]);
            //效验相识度有没有达到设置要求
            if(similarRate>CommonConstants.COMPARE_ROOM_BED_NAMR_PRE){
                //判断是否不能组合，如果不符合组合要求过滤父360不能与子370、657和852组合
                if((ParentId== SwitchBedIdEnums.BIG.getParentId())&&(SwitchBedIdEnums.BIG.getChidlds().contains(String.valueOf(bedIds[i])))){
                    bedId=(similarRate>moreSimilar)?bedIds[i]:bedId;
                    moreSimilar=(similarRate>moreSimilar)?similarRate:moreSimilar;
                }
                //父361不能与子365、370、4059、4060和4061组合
                if((ParentId==SwitchBedIdEnums.DOUBLE.getParentId())&&(SwitchBedIdEnums.BIG.getChidlds().contains(String.valueOf(bedIds[i])))){
                    bedId=(similarRate>moreSimilar)?bedIds[i]:bedId;
                    moreSimilar=(similarRate>moreSimilar)?similarRate:moreSimilar;
                }
                //父362能与子370、852和851组合
                if((ParentId==SwitchBedIdEnums.SINGLE.getParentId())&&(SwitchBedIdEnums.SINGLE.getChidlds().contains(String.valueOf(bedIds[i])))){
                    bedId=(similarRate>moreSimilar)?bedIds[i]:bedId;
                    moreSimilar=(similarRate>moreSimilar)?similarRate:moreSimilar;
                }
                //父363能与除852的子组合
                if((ParentId==SwitchBedIdEnums.MUCH.getParentId())&&!(SwitchBedIdEnums.MUCH.getChidlds().contains(String.valueOf(bedIds[i])))){
                    bedId=(similarRate>moreSimilar)?bedIds[i]:bedId;
                    moreSimilar=(similarRate>moreSimilar)?similarRate:moreSimilar;
                }
            }else{
                continue tab;
            }
        }
        return bedId;
    }

    /**
     * 获取餐食规则
     * @param goodsName
     */
    public static int getBreakFast(String goodsName){
       String[] items=goodsName.split("-");
       String[] names=new String[]{"不定","无早","单早","含早","双早","早+晚餐","早+午餐","早+午+晚餐","晚餐"+"午餐"+"午+晚餐"};
       int breakId=0;
       int[] breakIds=new int[]{6,498160,7,8,640292,111,460276,112,1211906,5454133,5454137};
        if(items.length<2){//说明对比出现问题
            return breakId;
        }
        String itemName=items[1];
        if(itemName.contains("不含早")){
            breakId=Arrays.binarySearch(names,"不定");
        }
        if(itemName.equals("含单早")){
            breakId=Arrays.binarySearch(names,"单早");
        }
        if(itemName.equals("含双早")){
            breakId=Arrays.binarySearch(names,"双早");
        }
        return breakIds[breakId];
    }

    /**
     * 获取携程房价
     * @param salePrice 美团的价格
     * @Param switchPrice 携程价格
     * @return
     */
    public static double getPrice(Integer salePrice,double switchPrice) {
        int prices[]=new int[]{5,4,3,2,1};
        float mutil=(float)salePrice/100;
        if(switchPrice==0){
            return mutil+prices[0];
        }else{
            int index=Integer.valueOf(String.valueOf(switchPrice-mutil))-1;
            if(index>=5){
                return 0;
            }else{
                return mutil+prices[index+1];
            }
        }
    }

    /**
     * 去除符合
     * @param name
     */
    public static String removeSymbol(String name){
        int index=name.indexOf("(");
        //说明在开头位置
        if(index==0){
            log.info("=========出现(的位置为{}",index);
            index=name.indexOf(")");
            log.info("=========出现)的位置为{}",index);
            name=name.substring(index);
        }else if(index>0){
            log.info("=========出现(的位置为{}",index);
            name=name.substring(0,index);
        }
        index=name.indexOf("【");
        if(index==0){
            log.info("=========出现【的位置为{}",index);
            index=name.indexOf("】");
            log.info("=========出现】的位置为{}",index);
            name=name.substring(index);
        }else if(index>0){
            log.info("=========出现【的位置为{}",index);
            name=name.substring(0,index);
        }
        return name;
    }
    /***
    * @Author: lmf
    * @Date: 2020/12/21
     * 比较俩个是否串是否一样
    */
    private static boolean IsSame(String str1, String str2) {
        HashSet hs = new HashSet();
        for(int i=0; i<str1.length(); i++){
            hs.add(str1.charAt(i));
        }
        int temp = hs.size();
        for(int i=0; i<str2.length(); i++){
            hs.add(str2.charAt(i));
        }
        if(temp == hs.size()) return true;
        return false;
    }


    public static void main(String[] args) {
       /*   String str="{\"name\":\"guolicheng\",\"id\":123456,\"date\":\"2013-4-13 12:36:54\"}";
          String str2="{\"id\":123456,\"name\":\"guolicheng\",\"date\":\"2013-4-13 12:36:54\"}";
          if(str.equals(str2)){
              System.out.println("真好看");
          }else{
              System.out.println("真不好看");
          }*/
        String goodName="家庭房,高";
        String mtRoomName="高级家庭房";
        System.out.println(CompareUtil.IsSame(goodName,mtRoomName));
//        String str = "云南西双版纳听雨轩酒店" ;
//        String target = "西双版纳听雨轩客栈（(曼)听店）";
//
//        long startTime1 = System.currentTimeMillis();    //获取开始时间
//        log.info("startTime1 :"+ startTime1);

//        Result parse = NlpAnalysis.parse(str);
//        System.out.println(parse);

//
//        Result result = ToAnalysis.parse(str);
//        System.out.println(result);
//        KeyWordComputer kwc = new KeyWordComputer(1);
//        Collection<Keyword> keywords = kwc.computeArticleTfidf(str);
//        System.out.println(keywords);


//        boolean pre = getStrPre("云南",target,str);


//        System.out.println(">>>>-------"+pre);
//        float per = getSimilarityRatio(target,str);
//        log.info("pre :"+ pre);
//
//        long endTime1 = System.currentTimeMillis();    //获取结束时间
//        log.info("endTime1 :"+ endTime1);
//
//        log.info("运行时间1： {}",(endTime1 - startTime1) + "ms");


        /*double d = 31849509;
        System.out.println(getDouble(d));

        double lat1 = 31.849509;
        double lng1 = 106.765018;

        log.info("lat1:" + lat1);
        log.info("lng1:" + lng1);
        double lat11 = GCJ2WGSUtils.WGSLat(lat1, lng1);
        double lng11 = GCJ2WGSUtils.WGSLon(lat1, lat1);

        log.info("lat11:" + lat11);
        log.info("lng11:" + lng11);
        double lat2 = 31.849519;
        double lng2 = 106.765028;
        log.info("lat2:" + lat2);
        log.info("lng2:" + lng2);

        double lat22 = GCJ2WGSUtils.WGSLat(lat2, lng2);
        double lng22 = GCJ2WGSUtils.WGSLon(lat2, lat2);
        log.info("lat22:" + lat22);
        log.info("lng22:" + lng22);

        GlobalCoordinates source = new GlobalCoordinates(lat11, lng11);
        GlobalCoordinates target = new GlobalCoordinates(lat22, lng22);

        double meter1 = CaculateDistance.getDistanceMeter(source, target, Ellipsoid.WGS84);

        log.info("meter1:" + meter1 + "米");

        double meter2 = algorithm(lat1, lng1, lat2, lng2);
        log.info("meter2:" + meter2 + "米");*/

        double lat1 = 25.279969;
        double lng1 = 117.427236;

        double lat2 = 25.279847;
        double lng2 = 117.427126;

        double meter2 = algorithm(lat1, lng1, lat2, lng2);

        log.info("meter2----------------||||| :  {} ", meter2);


//        log.info("1111111111----------------||||| :"+ String.format("%.6f", Double.valueOf(106765018)));


//        String str = "锦江都城" ;
//        System.out.println(">>>>>>>>>>>>"+ ToAnalysis.parse(str).size());
//        System.out.println(">>>>>>>>>>>>"+ ToAnalysis.parse(str).get(0));
//
//
//        String str2 = "锦江都城(徐家汇南华亭)" ;
//        System.out.println(">>>>>>>>>>>>"+ ToAnalysis.parse(str2).size());
//        System.out.println(">>>>>>>>>>>>"+ ToAnalysis.parse(str2).get(0));
//
//
//
//        Map<String, String> map = new HashMap<String, String>();
//        map.put("1", "value1");
//        map.put("2", "value2");
//        map.put("3", "value3");
//        map.put("4", "value1");
//        map.put("5", "value2");
//        map.put("6", "value3");
//        map.put("7", "value2");
//        map.put("8", "value3");
//        map.put("9", "value1");
//        map.put("11", "value2");
//        map.put("12", "value3");
//        map.put("13", "value3");
//        map.put("14", "value1");
//        map.put("15", "value2");
//        map.put("16", "value3");
//        map.put("17", "value2");
//        map.put("18", "value3");
//        map.put("19", "value1");
//        map.put("21", "value1");
//        map.put("22", "value2");
//        map.put("23", "value3");
//        map.put("24", "value1");
//        map.put("25", "value2");
//        map.put("26", "value3");
//        map.put("27", "value2");
//        map.put("28", "value3");
//        map.put("29", "value1");
//
//        //第一种：普遍使用，二次取值
//        System.out.println("通过Map.keySet遍历key和value：");
//        long startTime1 = System.currentTimeMillis();    //获取开始时间
//        log.info("startTime1 :"+ startTime1);
//        for (String key : map.keySet()) {
//            System.out.println("key= "+ key + " and value= " + map.get(key));
//        }
//        long endTime1 = System.currentTimeMillis();    //获取结束时间
//        log.info("endTime1 :"+ endTime1);
//
//        log.info("运行时间1： {}",(endTime1 - startTime1) + "ms");
//
//        //第二种
//        System.out.println("通过Map.entrySet使用iterator遍历key和value：");
//
//        long startTime2 = System.currentTimeMillis();    //获取开始时间
//        log.info("startTime2 :"+ startTime2);
//        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
//        while (it.hasNext()) {
//            Map.Entry<String, String> entry = it.next();
//            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
//        }
//
//        long endTime2 = System.currentTimeMillis();    //获取结束时间
//        log.info("endTime2 :"+ endTime2);
//
//        log.info("运行时间2： {}",(endTime2 - startTime2) + "ms");
//
//
//        //第三种：推荐，尤其是容量大时
//        System.out.println("通过Map.entrySet遍历key和value");
//        long startTime3 = System.currentTimeMillis();    //获取开始时间
//        log.info("startTime3 :"+ startTime3);
//        for (Map.Entry<String, String> entry : map.entrySet()) {
//            System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
//        }
//
//        long endTime3 = System.currentTimeMillis();    //获取结束时间
//        log.info("endTime3 :"+ endTime3);
//
//        log.info("运行时间3： {}",(endTime3 - startTime3) + "ms");
//
//        //第四种
//        System.out.println("通过Map.values()遍历所有的value，但不能遍历key");
//        long startTime4 = System.currentTimeMillis();    //获取开始时间
//        log.info("startTime4 :"+ startTime4);
//        for (String v : map.values()) {
//            System.out.println("value= " + v);
//        }
//
//        long endTime4 = System.currentTimeMillis();    //获取结束时间
//        log.info("endTime4 :"+ endTime4);
//
//        log.info("运行时间4： {}",(endTime4 - startTime4) + "ms");
//System.out.println(Double.valueOf(String.format("%.6f", Double.valueOf(117517759) / 1000000)));
    }

}
